open Mips

type var = {
	var_id : int;
	var_mem_adr : int;
	var_mem_size : int;
	var_nom : string;
	var_type : string; (* @todo *)
}

(*type registre = {
	var_reg : Mips.register;
	var_var : var;
}*)
	

let lid = ref 0

(* Les registre qui seront outilise de facon autimatique *)
let usableRegisters = ref [T1; T2; T3; T4; T5; T6; T7; T8; T9]

let createVar (nom:string) (vtype:string) (adr:int) (size:int) = 
	let x = {
		var_id = !lid;
		var_mem_adr = adr;
		var_mem_size = size;
		var_nom = nom;
		var_type = vtype
	} in
	lid := !lid + 1;
	x
	
let getId (v:var) = 
	v.var_id
	
let getNom (v:var) = 
	v.var_nom
	
let getSize (v:var) = 
	v.var_mem_size
	
let getAdr (v:var) = 
	v.var_mem_adr
	
let getType (v:var) = 
	v.var_type

let loadVar (v:var) = 
	([(Lw(Mips.T0, Areg(v.var_mem_adr,SP)))], Mips.T0)

let load2Vars (v1: var) (v2: var) = 
	( [(Lw(Mips.T1, Areg(v1.var_mem_adr,SP))); (Lw(Mips.T2, Areg(v2.var_mem_adr,SP)))], [Mips.T1; Mips.T2])

(* Va charger la variable dans le registre *)
let loadVarIn (v:var) (r:Mips.register) = 
	[(Lw(r, Areg(v.var_mem_adr,SP)))]

let loadVars vs = 
	let rec loop vs rs = 
		match (vs, rs) with
			| ((v::[]),(r::_)) -> ((loadVarIn v r),[r])
			| ((v::vs),(r::[])) -> assert false
			| ((v::vs), (r::rs)) -> 
				let (il, rs) = (loop vs rs) in		
					((loadVarIn v r)@il , r::rs)
			| _ , _ -> assert false 
	in
loop vs !usableRegisters

(* Va mettre la valeur qui est dans le registre dans la variable *)
let setVarFrom (v:var) (r:Mips.register) = 
	[(Sw(r, Areg(v.var_mem_adr,SP)))]


